package com.css.fxfzysx.modules.vabStructure.service.impl;


import com.alibaba.fastjson.JSON;
import com.css.fxfzysx.base.exception.ParamException;
import com.css.fxfzysx.base.response.RestResponse;
import com.css.fxfzysx.common.utils.BeanUtil;
import com.css.fxfzysx.constants.FxfzConstants;
import com.css.fxfzysx.constants.Src3Enum;
import com.css.fxfzysx.constants.Src4Enum;
import com.css.fxfzysx.constants.SrcFmckEnum;
import com.css.fxfzysx.modules.cztDataMange.constans.RedisKeyConstants;
import com.css.fxfzysx.modules.cztDataMange.entity.RcpInformationEntity;
import com.css.fxfzysx.modules.cztDataMange.repository.BacInformationRepository;
import com.css.fxfzysx.modules.cztDataMange.repository.RcpRepository;
import com.css.fxfzysx.modules.cztDataMange.utils.GenerationNumberUtil;
import com.css.fxfzysx.modules.cztDataMange.vo.RcpExcelSheet1Vo;
import com.css.fxfzysx.modules.cztDataMange.vo.RcpExcelSheet2Vo;
import com.css.fxfzysx.modules.cztDataMange.vo.RcpExcelSheet3Vo;
import com.css.fxfzysx.modules.cztDataMange.vo.RcpExcelSheet4Vo;
import com.css.fxfzysx.modules.vabStructure.constans.CorrectionCiEnum;
import com.css.fxfzysx.modules.vabStructure.entity.*;
import com.css.fxfzysx.modules.vabStructure.repository.*;
import com.css.fxfzysx.modules.vabStructure.repository.impl.CrsEntiretyCiRepository;
import com.css.fxfzysx.modules.vabStructure.service.SrcAnalyseService;
import com.css.fxfzysx.modules.vabStructure.utils.DoubleDecimal;
import com.css.fxfzysx.modules.vabStructure.utils.SrcAnaluseUtils;
import com.css.fxfzysx.modules.vabStructure.utils.TranslateDecimalUtils;
import com.css.fxfzysx.modules.vabStructure.utils.UnitTranslate;
import com.css.fxfzysx.modules.vabStructure.vo.*;
import com.css.fxfzysx.modules.ysxManagement.entity.CStructureCiEntity;
import com.css.fxfzysx.modules.ysxManagement.repository.RcStructureRepository;
import com.css.fxfzysx.util.*;
import com.css.fxfzysx.web.PlatformSessionContext;
import com.css.fxfzysx.zcpt.sys.entity.SUser;
import com.css.fxfzysx.zcpt.sys.service.SUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;


@Service
@Slf4j
public class SrcAnalyseServiceImpl implements SrcAnalyseService {

    @Autowired
    CrsStoreyCalResultRespository crsStoreyCalResultRespository;

    @Autowired
    CrsColumnCalResultRepository crsColumnCalResultRepository;

    @Autowired
    CrsEntiretyCalResultRepository crsEntiretyCalResultRepository;

    @Autowired
    BacInformationRepository bacInformationRepository;

    @Autowired
    GenerationNumberUtil generationNumberUtil;

    @Autowired
    CrsMatrixCalResultRepository crsMatrixCalResultRepository;

    @Autowired
    CrsRoofbeamCalRepository crsRoofbeamCalRepository;

    @Autowired
    private SrcAnaluseUtils srcAnaluseUtils;

    @Autowired
    private CrsEntiretyCiRepository crsEntiretyCiRepository;

    @Autowired
    private RcStructureRepository rcStructureRepository;

    @Autowired
    RcpInformationRepository rcpInformationRepository;

    @Autowired
    private RcpRepository rcpRepository;

    private CrsAnalyseVO analyseVO = new CrsAnalyseVO();

    @Autowired
    private ThreadPoolUtil threadPoolUtil;

    @Autowired
    private CztCrsCalTcqResultRepository tcqResultRepository;
    @Autowired
    private CztCrsCalJlqResultRepository jlqResultRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, List> calculatesResult(Map<String, Object> paramMap) throws Exception {
        analyseVO = new CrsAnalyseVO();
        //准备参数。
        paramMap = prepareParam(paramMap);
        analyseVO.setNumber(generateNum(paramMap));
        Map<Integer, List<CztCrsCalColumnResult>> storeyMap = new HashMap<>();
        List<CztCrsCalColumnResult> columnResults = calculateColumn(paramMap);
        Map<Integer, List<CztCrsCalColumnResult>> collect = columnResults.stream().collect(Collectors.groupingBy(CztCrsCalColumnResult::getFloorNum));
        Map<Integer, Double> qcMap = new HashMap<>();
        collect.forEach((key, value) -> {
            double sum = value.stream().mapToDouble(CztCrsCalColumnResult::getQcz).sum();
            qcMap.put(key, sum);
        });
        List<ColumnVO> columnVOS = new ArrayList<>();
        for (CztCrsCalColumnResult entity : columnResults) {
            if (PlatformObjectUtils.isEmpty(storeyMap) || PlatformObjectUtils.isEmpty(storeyMap.get(entity.getFloorNum()))) {
                List<CztCrsCalColumnResult> storeyList = new ArrayList<>();
                storeyList.add(entity);
                storeyMap.put(entity.getFloorNum(), storeyList);
            } else {
                List<CztCrsCalColumnResult> storeyList = storeyMap.get(entity.getFloorNum());
                storeyList.add(entity);
                storeyMap.put(entity.getFloorNum(), storeyList);
            }
            List<ColumnVO> columns = (List<ColumnVO>) paramMap.get(FxfzConstants.columnPam);
            for (ColumnVO column : columns) {
                if (column.getPillarCode().equals(entity.getPillarCode())) {
                    entity.setQz(qcMap.get(entity.getFloorNum()));
                    BeanUtil.copyPropertiesIgnoreEmpty(entity, column);
                    column.setQz(qcMap.get(column.getFloorNum()));
                    column = (ColumnVO) TranslateDecimalUtils.unUnitTranslate(column, UnitTranslate.class);
                    columnVOS.add(column);
                }
            }
            entity = (CztCrsCalColumnResult) TranslateDecimalUtils.unUnitTranslate(entity, UnitTranslate.class);
            crsColumnCalResultRepository.save(entity);
        }


        CrsEntiretyParamVo crsEntiretyParamVo = new CrsEntiretyParamVo();
        List<CrsEntiretyParamVo> list = (List) paramMap.get(FxfzConstants.entiretyPam);
        crsEntiretyParamVo = list.get(0);
        List<CztCrsStoreyCalResult> storeyCalResults = calculateStorey(storeyMap, paramMap);
        for (CztCrsStoreyCalResult storey : storeyCalResults) {
            crsStoreyCalResultRespository.save(storey);
        }
        CztCrsEntiretyCalResult entiretyCalResult = new CztCrsEntiretyCalResult();
        BeanUtil.copyPropertiesIgnoreEmpty(paramMap.get(FxfzConstants.entiretyPam), entiretyCalResult);
        if (PlatformObjectUtils.isNotEmpty(crsEntiretyParamVo.getCalId())) {
            CztCrsEntiretyCalResult oldEntiretyResult = crsEntiretyCalResultRepository.findByCalId(crsEntiretyParamVo.getCalId());
            if (PlatformObjectUtils.isNotEmpty(oldEntiretyResult)) {
                if ("1".equals(paramMap.get("calculate_ornot"))) {
                    oldEntiretyResult.setCalculate_or_not("1");
                }
                BeanUtil.copyPropertiesIgnoreEmpty(crsEntiretyParamVo, oldEntiretyResult);
                entiretyCalResult = oldEntiretyResult;
            } else {
                BeanUtil.copyPropertiesIgnoreEmpty(crsEntiretyParamVo, entiretyCalResult);
                entiretyCalResult.setCalId(analyseVO.getEntiretyId());
                entiretyCalResult.setNumber(analyseVO.getNumber());
                entiretyCalResult.setDelFlag("0");
                entiretyCalResult.setCalculate_or_not("1");
                entiretyCalResult.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                entiretyCalResult.setCreateUserId(PlatformSessionUtils.getUserId());
            }
        } else {
            BeanUtil.copyPropertiesIgnoreEmpty(crsEntiretyParamVo, entiretyCalResult);
            entiretyCalResult.setCalId(analyseVO.getEntiretyId());
            entiretyCalResult.setNumber(analyseVO.getNumber());
            entiretyCalResult.setDelFlag("0");
            entiretyCalResult.setCalculate_or_not("1");
            entiretyCalResult.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            entiretyCalResult.setCreateUserId(PlatformSessionUtils.getUserId());
            entiretyCalResult.setStructureType("钢筋混凝土");
//            entiretyCalResult.setDeptId(sysDeptService.getMainDeptByUserId(PlatformSessionUtils.getUserId()));
        }
        entiretyCalResult = (CztCrsEntiretyCalResult) TranslateDecimalUtils.translate2De(entiretyCalResult, DoubleDecimal.class);

        entiretyCalResult.setDataType(FxfzConstants.CZT_GJHNT_INFO);
        crsEntiretyCalResultRepository.save(entiretyCalResult);
        ArrayList<CztCrsEntiretyCalResult> cztCrsEntiretyCalResults = new ArrayList<>();
        cztCrsEntiretyCalResults.add(entiretyCalResult);
        Map<String, List> resultMap = new HashMap<>();
        List<CztCrsMatrixCalResult> matrixCalResults = crsMatrixCalResultRepository.findByEntiretyId(analyseVO.getEntiretyId());
        List<CztCrsJlqCalResult> jlqCalResults = jlqResultRepository.findByEntiretyId(analyseVO.getEntiretyId());
        List<CztCrsTcqCalResult> tcqCalResults = tcqResultRepository.findByEntiretyId(analyseVO.getEntiretyId());
        resultMap.put(FxfzConstants.entiretyResult, cztCrsEntiretyCalResults);
        resultMap.put(FxfzConstants.columnResult, columnVOS);
        resultMap.put(FxfzConstants.storeyResult, storeyCalResults);
        resultMap.put(FxfzConstants.matrixResult, matrixCalResults);
        resultMap.put(FxfzConstants.jlqResult, jlqCalResults);
        resultMap.put(FxfzConstants.tcqResult, tcqCalResults);
        return resultMap;
    }


    @Override
    public Map<String, List> queryResult(String calId) {
        //如果是从菜单直接点进来的话，calId 是空值。
        Map resultMap = new HashMap<>();
//        CStructureCiVo cStructureCiVo = srcAnaluseUtils.getAllCStructureCi(FxfzConstants.crsCi,calId);
//        resultMap.put("ci",cStructureCiVo);
        if (PlatformObjectUtils.isNotEmpty(calId)) {
            //先确定是否计算了。
            CztCrsEntiretyCalResult entiretyCalResult = crsEntiretyCalResultRepository.findByCalId(calId);
            List entiretyCalResults = new ArrayList();
            entiretyCalResults.add(entiretyCalResult);
            List<CztCrsCalColumnResult> rcpInformationEntities = crsColumnCalResultRepository.findByEntiretyId(calId);
            List<ColumnVO> columnVOS = new ArrayList<>();
            for (CztCrsCalColumnResult column : rcpInformationEntities) {
                List<CztCrsCalRoofbeamResult> crsBeamVOS = crsRoofbeamCalRepository.findByColumnId(column.getCalId());
                RcpInformationEntity rcpInformationEntity = rcpRepository.findByCcpiId(column.getCcpiId());
                ColumnVO columnVO = new ColumnVO();
                BeanUtil.copyPropertiesIgnoreEmpty(rcpInformationEntity, columnVO);
                BeanUtil.copyPropertiesIgnoreEmpty(column, columnVO);
                if (PlatformObjectUtils.isNotEmpty(crsBeamVOS)) {
                    BeanUtil.copyPropertiesIgnoreEmpty(crsBeamVOS.get(0), columnVO);
                }
               /* if(PlatformObjectUtils.isNotEmpty(crsBeamVOS)){
                    columnVO.setRoofBeam(crsBeamVOS.get(0));
                }*/
                columnVOS.add(columnVO);
            }
            List<CztCrsStoreyCalResult> storeyCalResults = crsStoreyCalResultRespository.findByEntiretyIdOrderByFloorNum(calId);
            List<CztCrsJlqCalResult> jlqCalResults = jlqResultRepository.findByEntiretyId(calId);
            List<CztCrsTcqCalResult> tcqCalResults = tcqResultRepository.findByEntiretyId(calId);
            resultMap.put(FxfzConstants.columnResult, columnVOS);
            resultMap.put(FxfzConstants.entiretyResult, entiretyCalResults);
            resultMap.put(FxfzConstants.storeyResult, storeyCalResults);
            resultMap.put(FxfzConstants.tcqResult, tcqCalResults);
            resultMap.put(FxfzConstants.jlqResult, jlqCalResults);


            if (PlatformObjectUtils.isNotEmpty(entiretyCalResult) && entiretyCalResult.getCalculate_or_not().equals("1")) {
                List<CztCrsCalColumnResult> columnCalResults = crsColumnCalResultRepository.findByEntiretyId(calId);
                for (CztCrsCalColumnResult column : rcpInformationEntities) {
                    for (CztCrsCalColumnResult columnResult : columnCalResults) {
                        if (column.getPillarCode().equals(columnResult.getPillarCode())) {
                            int index = rcpInformationEntities.indexOf(column);
                            BeanUtil.copyPropertiesIgnoreEmpty(columnResult, column);
                            rcpInformationEntities.set(index, column);
                        }
                    }
                }
                //resultMap.put(FxfzConstants.columnResult, rcpInformationEntities);

                List<CztCrsMatrixCalResult> cztCrsMatrixCalResults = crsMatrixCalResultRepository.findByEntiretyId(calId);
                //Map<Integer, List<CztCrsMatrixCalResult>> collect = cztCrsMatrixCalResults.stream().collect(Collectors.groupingBy(CztCrsMatrixCalResult::getFloorNum));
                resultMap.put(FxfzConstants.matrixResult, cztCrsMatrixCalResults);
            }

        }

        return resultMap;
    }

    @Override
    public void saveModel(String calId) {
        CztCrsEntiretyCalResult cztCrsEntiretyCalResult = crsEntiretyCalResultRepository.findByCalId(calId);
        if (PlatformObjectUtils.isNotEmpty(cztCrsEntiretyCalResult)) {
            cztCrsEntiretyCalResult.setDelFlag("0");
            cztCrsEntiretyCalResult.setCalculate_or_not("1");
            cztCrsEntiretyCalResult.setDataType(FxfzConstants.CZT_GJHNT_INFO);
            crsEntiretyCalResultRepository.save(cztCrsEntiretyCalResult);
        } else {
            throw new RuntimeException("未找到需要保存数据，请重新计算！");
        }
        List<CztCrsStoreyCalResult> storeyCalResults = crsStoreyCalResultRespository.findByEntiretyIdOrderByFloorNum(calId);
        if (PlatformObjectUtils.isNotEmpty(storeyCalResults)) {
            storeyCalResults.forEach(entity -> {
                entity.setDelFlag("0");
                entity = (CztCrsStoreyCalResult) TranslateDecimalUtils.unUnitTranslate(entity, UnitTranslate.class);
                crsStoreyCalResultRespository.save(entity);
            });
        } else {
            throw new RuntimeException("未找到需要保存的楼层数据，请重新计算！");
        }
        List<CztCrsMatrixCalResult> matrixCalResults = crsMatrixCalResultRepository.findByEntiretyId(calId);
        if (PlatformObjectUtils.isNotEmpty(matrixCalResults)) {
            matrixCalResults.forEach(entity -> {
                entity.setDelFlag("0");
                crsMatrixCalResultRepository.save(entity);
            });
        } else {
            throw new RuntimeException("未找到需要保存的矩阵数据，请重新计算！");
        }
        List<CztCrsCalColumnResult> columnResults = crsColumnCalResultRepository.findByEntiretyId(calId);
        if (PlatformObjectUtils.isNotEmpty(columnResults)) {
            columnResults.forEach(entity -> {
                entity.setDelFlag("0");
                entity = (CztCrsCalColumnResult) TranslateDecimalUtils.unUnitTranslate(entity, UnitTranslate.class);
                crsColumnCalResultRepository.save(entity);
            });
        } else {
            throw new RuntimeException("未找到需要保存的柱子数据，请重新计算！");
        }
        List<CztCrsEntiretyCi> entiretyCis = crsEntiretyCiRepository.findByEntiretyId(calId);
        if (PlatformObjectUtils.isNotEmpty(entiretyCis)) {
            entiretyCis.forEach(entity -> {
                entity.setDelFlag("0");
                crsEntiretyCiRepository.save(entity);
            });
        }

    }

    //只有修改模型数据的时候才会重新计算，重新计算的时候也只是修改模型中用到的数据即可;
    //模型计算中用到了三个值，1是ci 2是fv  3是xigemaN 后两个是用来计算mcy 的值，ci 是用来计算u 的值;
    @Override
    public void reCalculates(String calIds) throws Exception {
        String[] str = calIds.split(",");
        //todo 这个线程池大小不合理，需要再看。是不是写成固定值？
        int n = threadPoolUtil.countThreadNum(10, str.length);
        //创建线程池
        ExecutorService executorService = threadPoolUtil.getFixedThreadPool(n);
        for (int i = 0; i < str.length; i++) {
            String calId = str[i];
            executorService.execute(() -> {
                try {
                    excuteRecalculate(calId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    private void excuteRecalculate(String calId) throws Exception {
        Map<String, Object> paramMap = new HashMap<>();
        CztCrsEntiretyCalResult entirety = crsEntiretyCalResultRepository.findByCalId(calId);
        List<CztCrsEntiretyCalResult> entiretyCalResults = new ArrayList<>();
        entiretyCalResults.add(entirety);
        paramMap.put(FxfzConstants.entiretyPam, entiretyCalResults);

        List<ColumnVO> columnVOS = rcpInformationRepository.findByEntiretyId(calId);
        for (ColumnVO column : columnVOS) {
            int index = columnVOS.indexOf(column);
            List<CztCrsCalRoofbeamResult> roofbeams = crsRoofbeamCalRepository.findByColumnId(column.getCcpiId());
            column.setRoofBeam(roofbeams.get(0));
            columnVOS.set(index, column);
        }
        paramMap.put(FxfzConstants.columnPam, columnVOS);

        List<CztCrsStoreyCalResult> storeyCalResults = crsStoreyCalResultRespository.findByEntiretyIdOrderByFloorNum(calId);
        paramMap.put(FxfzConstants.storeyPam, storeyCalResults);

        List<CztCrsEntiretyCi> entiretyCis = crsEntiretyCiRepository.findByEntiretyId(calId);
        List<String> ciIds = new ArrayList<>();
        for (CztCrsEntiretyCi ciEntity : entiretyCis) {
            ciIds.add(ciEntity.getCiId());
        }
        paramMap.put(FxfzConstants.ckPam, ciIds);
        paramMap.put("calculate_ornot", "1");
        this.calculatesResult(paramMap);
    }

    @Override
    public void importCrsBuildings(String calIds, HttpServletResponse response) {
        ArrayList<CrsEntiretyResultVO> entiretys = new ArrayList<>();
        for (String calId : calIds.split(",")) {
            CztCrsEntiretyCalResult entiretyCalResult = crsEntiretyCalResultRepository.findByCalId(calId);
            CrsEntiretyResultVO crsEntiretyResultVO = new CrsEntiretyResultVO();
            BeanUtil.copyPropertiesIgnoreEmpty(entiretyCalResult, crsEntiretyResultVO);
            crsEntiretyResultVO.setRegion(crsEntiretyResultVO.getProvince() + "-" + crsEntiretyResultVO.getCity() + "-" + crsEntiretyResultVO.getCounty());
            crsEntiretyResultVO.setSt(crsEntiretyResultVO.getStructureType() + "-" + crsEntiretyResultVO.getStructureType1());
            crsEntiretyResultVO.setUse(crsEntiretyResultVO.getPurpose() + "-" + crsEntiretyResultVO.getPurpose1());
            entiretys.add(crsEntiretyResultVO);
        }
        try {
            FileUtil.exportExcel(entiretys, "钢筋混凝土信息", "sheet1", CrsEntiretyResultVO.class, "钢筋混凝土信息.xlsx", response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param list 将一个建筑的柱参数，梁参数、填充墙、剪力墙参数放到list中传过来。
     * @return 因为之前的接口是写好的，所以为了调用之前的接口需要将参数重新组装成之前接口map 的形式。
     */
    @Autowired
    private SUserService userService;

    @Override
    public RestResponse calculate(List<List> list) throws Exception {
        //重新写计算
        RestResponse restResponse = null;
    /*    try {
            Map<String, List> stringListMap = this.calculatesResult(paramMap);
        } catch (Exception e) {

        }*/
        try {
            //柱参数
            List<RcpExcelSheet1Vo> list1 = list.get(0);
            //梁参数
            List<RcpExcelSheet2Vo> list2 = list.get(1);
            //剪力墙参数
            List<RcpExcelSheet3Vo> list3 = list.get(2);
            //填充墙参数
            List<RcpExcelSheet4Vo> list4 = list.get(3);

            CrsEntiretyParamVo entiretyCalResult = new CrsEntiretyParamVo();
            //默认list1 中所有的建筑信息参数都相同，所以任意取一个。
            RcpExcelSheet1Vo rcpExcelSheet1Vo = list1.get(0);
            BeanUtil.copyPropertiesIgnoreEmpty(rcpExcelSheet1Vo, entiretyCalResult);
            entiretyCalResult.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            String user = userService.getSUser(PlatformSessionContext.getUserID());
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            entiretyCalResult.setUserName(sUser.getUserName());
            //处理ci
            entiretyCalResult.setCiType1("现浇钢筋混凝土构件沿高度断面无突变");
            entiretyCalResult.setCiType1Value(rcpExcelSheet1Vo.getXjzgjwtb().equals("满足") ? 0 : 1);
            entiretyCalResult.setCiType2("平面对称");
            entiretyCalResult.setCiType2Value(rcpExcelSheet1Vo.getPmgz().equals("是") ? 0 : 1);
            entiretyCalResult.setCiType3("施工质量良好");
            entiretyCalResult.setCiType3Value(rcpExcelSheet1Vo.getSgzllh().equals("满足") ? 0 : 1);
            entiretyCalResult.setCiType4("建筑抗震设计规范");
            //这个取值怎么取？
            entiretyCalResult.setCiType4Value(CorrectionCiEnum.getByValue(rcpExcelSheet1Vo.getJzkzgf()));
            ArrayList<CrsEntiretyParamVo> crsEntiretyParamVos = new ArrayList<>();
            crsEntiretyParamVos.add(entiretyCalResult);
            //获取柱参数以及梁参数
            ArrayList<ColumnVO> rcpInformationEntities = new ArrayList<>();
            //柱参数转换
            for (RcpExcelSheet1Vo vo : list1) {
                ColumnVO columnVO = new ColumnVO();
                BeanUtil.copyPropertiesIgnoreEmpty(vo, columnVO);
                String pillarCode = columnVO.getPillarCode();
                //找到当前柱子的梁参数
                List<RcpExcelSheet2Vo> sheet2Vos = list2.stream().filter(item -> item.getPillarCode().equals(pillarCode)).collect(Collectors.toList());
                //正常情况下，最后一根柱子就是没有梁参数信息的。
                if (PlatformObjectUtils.isEmpty(sheet2Vos)) {
                    log.info("柱编号为:" + pillarCode + "的梁参数为空，请检查是否正常");
                } else {
                    for (RcpExcelSheet2Vo sheet2Vo : sheet2Vos) {
                        //梁参数需要拆分成4个; 现在柱编号是A、B、C ,梁编号是A-B ,B-C ，所以不同楼层的柱子编号和梁编号都是一样的。
                        CztCrsCalRoofbeamResult roofbeamResult = new CztCrsCalRoofbeamResult();
                        if (PlatformObjectUtils.isNotEmpty(sheet2Vo.getBeamNum())) {
                            //同一层的 并且同一根柱子的梁。再将梁参数转换
                            if (sheet2Vo.getFloorNum() == columnVO.getFloorNum() && sheet2Vo.getPillarCode().equals(pillarCode)) {
                                BeanUtil.copyPropertiesIgnoreEmpty(sheet2Vo, roofbeamResult);
                                columnVO.setRoofBeam(roofbeamResult);
                            }
                        }
                    }
                }
                rcpInformationEntities.add(columnVO);
            }
            //获取层参数
            Map<Integer, List<RcpExcelSheet1Vo>> storeyMap = list1.stream().collect(Collectors.groupingBy(RcpExcelSheet1Vo::getFloorNum));
            ArrayList<CrsStoreyVo> crsStoreyVos = new ArrayList<>();
            storeyMap.forEach((key, value) -> {
                CrsStoreyVo crsStoreyVo = new CrsStoreyVo();
                List<RcpExcelSheet1Vo> rcpExcelSheet1Vos = storeyMap.get(key);
                //正常情况下每一层应该只有一个参数。
                crsStoreyVo.setFloorNum(rcpExcelSheet1Vos.get(0).getFloorNum());
                crsStoreyVo.setFloorHeight(rcpExcelSheet1Vos.get(0).getFloorHeight());
                //建筑物宽度
                crsStoreyVo.setBuildWidth(rcpExcelSheet1Vos.get(0).getBuildWidth());
                //活荷载
                crsStoreyVo.setLiveLoad(rcpExcelSheet1Vos.get(0).getPerLoad());
                //每榀间距
                crsStoreyVo.setTrussSpacing(rcpExcelSheet1Vos.get(0).getTrussSpacing());
                //获取填充墙和剪力墙，并放到层参数中。
                Map<Integer, List<RcpExcelSheet3Vo>> tcqMap = new HashMap<>();
                Map<Integer, List<RcpExcelSheet4Vo>> jlqMap = new HashMap<>();
                if (PlatformObjectUtils.isNotEmpty(list3)) {
                    tcqMap = list3.stream().collect(Collectors.groupingBy(RcpExcelSheet3Vo::getFloorNum));
                    List<RcpExcelSheet3Vo> rcpExcelSheet3Vos = tcqMap.get(key);
                    crsStoreyVo.setTcqList(rcpExcelSheet3Vos);
                    List<RcpExcelSheet3Vo> collect = list3.stream().filter(entity -> entity.getFloorNum().equals(crsStoreyVo.getFloorNum())).collect(Collectors.toList());
                    if (PlatformObjectUtils.isNotEmpty(collect)) {
                        crsStoreyVo.setTcqList(collect);
                    }
                }
                if (PlatformObjectUtils.isNotEmpty(list4)) {
                    jlqMap = list4.stream().collect(Collectors.groupingBy(RcpExcelSheet4Vo::getFloorNum));
                    List<RcpExcelSheet4Vo> rcpExcelSheet4Vos = jlqMap.get(key);
                    crsStoreyVo.setJlqList(rcpExcelSheet4Vos);
                    List<RcpExcelSheet4Vo> collect1 = list4.stream().filter(entity -> entity.getFloorNum().equals(crsStoreyVo.getFloorNum())).collect(Collectors.toList());
                    if (PlatformObjectUtils.isNotEmpty(collect1)) {
                        crsStoreyVo.setJlqList(collect1);
                    }
                }
                crsStoreyVo.setNumberOfPieces(rcpExcelSheet1Vos.get(0).getPs());
                crsStoreyVos.add(crsStoreyVo);
            });

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put(FxfzConstants.entiretyPam, crsEntiretyParamVos);
            paramMap.put(FxfzConstants.storeyPam, crsStoreyVos);
            paramMap.put(FxfzConstants.columnPam, rcpInformationEntities);
            Map<String, List> stringListMap = this.calculatesResult(paramMap);
            restResponse = RestResponse.succeed(stringListMap);
            return restResponse;
        } catch (Exception e) {
            e.printStackTrace();
            restResponse = RestResponse.fail(e.getMessage());
            return restResponse;
        }

    }

    // 返回的应该是一个map的list<CztCrsCalColumnResult>,list<CztCrsStoreyCalResult>; 或者List的计算对象。
    private List<CztCrsCalColumnResult> calculateColumn(Map<String, Object> paramMap) {
        List<ColumnVO> dataList = (List) paramMap.get(FxfzConstants.columnPam);
        List<CrsStoreyVo> storeyVos = (List<CrsStoreyVo>) paramMap.get(FxfzConstants.storeyPam);
        List<CztCrsCalColumnResult> columnResults = new ArrayList<>();
        //将每层的柱子分组；
        Map<Integer, List<ColumnVO>> columnMap = dataList.stream().collect(Collectors.groupingBy(ColumnVO::getFloorNum));
        for (CrsStoreyVo storey : storeyVos) {
            List<ColumnVO> columnVOS = columnMap.get(storey.getFloorNum());
            List<CztCrsCalRoofbeamResult> collect = columnVOS.stream().map(ColumnVO::getRoofBeam).collect(Collectors.toList());
            //将每层的梁都作为参数放到层对象里。
            storey.setRoofbeamResults(collect);
        }
        //需要上下两根柱子作为参数
        columnMap.forEach((key, value) -> {
            for (ColumnVO entity : columnMap.get(key)) {
                //下一层的柱子。
                ColumnVO lastEntity = new ColumnVO();
                if (PlatformObjectUtils.isNotEmpty(columnMap.get(key - 1))) {
                    //柱子编号的格式是（1-A ,2-A ....）  所以按照楼层分组最终得到上下柱子的参数。
                    String lastCode = entity.getPillarCode();
                    lastEntity = columnMap.get(key - 1).stream().filter(item -> item.getPillarCode().equals(lastCode)).collect(Collectors.toList()).get(0);
                }
                //上一层的柱子
                ColumnVO nextEntity = new ColumnVO();
                if (PlatformObjectUtils.isNotEmpty(columnMap.get(key + 1))) {
                    String nextCode = entity.getPillarCode();
                    nextEntity = columnMap.get(key + 1).stream().filter(item -> item.getPillarCode().equals(nextCode)).collect(Collectors.toList()).get(0);
                }
                CztCrsCalColumnResult columnResult = calculateQcz(lastEntity, entity, nextEntity, storeyVos);
                //保存所有的梁参数,有的柱子没梁。

                CztCrsCalRoofbeamResult roofBeam = entity.getRoofBeam();
                if (PlatformObjectUtils.isNotEmpty(roofBeam)) {
                    CztCrsCalRoofbeamResult newRoofBeam = new CztCrsCalRoofbeamResult();
                    BeanUtil.copyPropertiesIgnoreEmpty(roofBeam, newRoofBeam);
                    newRoofBeam.setCalId(UUIDGenerator.getUUID());
                    newRoofBeam.setEntiretyId(analyseVO.getEntiretyId());
                    newRoofBeam.setColumnNum(columnResult.getPillarCode());
                    newRoofBeam.setColumnId(columnResult.getCalId());
                    newRoofBeam.setDelFlag("0");
                    newRoofBeam = (CztCrsCalRoofbeamResult) TranslateDecimalUtils.unUnitTranslate(newRoofBeam, UnitTranslate.class);
                    crsRoofbeamCalRepository.save(newRoofBeam);
                }
                columnResults.add(columnResult);
            }
        });
        return columnResults;
    }

    /**
     * 计算砖填充墙钢筋混凝土框架结构的层间现有受剪承载力
     *
     * @param crsStoreyVo
     * @return
     * @throws Exception
     */

    private CztCrsStoreyCalResult calculateQmy(CrsStoreyVo crsStoreyVo) throws Exception {
        CztCrsStoreyCalResult storeyCalResult = new CztCrsStoreyCalResult();
        BeanUtil.copyPropertiesIgnoreEmpty(crsStoreyVo, storeyCalResult);
        double fve = 0.00;
        double qmy = 0.00;
        //一层不一定有多少填充墙，所以计算结果相加；
        if (PlatformObjectUtils.isNotEmpty(crsStoreyVo.getTcqList())) {
            for (RcpExcelSheet3Vo entity : crsStoreyVo.getTcqList()) {
                CztCrsTcqCalResult tcqCalResult = new CztCrsTcqCalResult();
                BeanUtil.copyPropertiesIgnoreEmpty(entity, tcqCalResult);
                tcqCalResult.setId(UUIDGenerator.getUUID());
                if (PlatformObjectUtils.isNotEmpty(entity.getTcqWidth())) {
                    String id = rcStructureRepository.getByGrade(entity.getScom());
                    //todo 这个单位不知道是什么？，先乘1000
                    double fvk = rcStructureRepository.getMasonryByIdAndType(id, entity.getBwCategory()) * 1000000;
                    //砌体类别,
                    double am = entity.getTcqWidth() * entity.getTcqThickness();
                    // 240403修改逻辑
                    double tem = entity.getTcqHeight() / (2 * entity.getTcqWidth());
                    double pow = Math.pow(tem, 2);
                    double sqrt = Math.sqrt(pow + 1);
                    fve = 1 / (sqrt - entity.getTcqHeight() / (2 * entity.getTcqWidth()));
                    double qm = fve * fvk * am;
                    double newQm = qm;
                    if (!tcqCalResult.getTcpNum().contains(crsStoreyVo.getPillarCodes())) {
                        newQm = newQm * 0.7;
                    }
                    qmy += newQm;
                    tcqCalResult.setEntiretyId(analyseVO.getEntiretyId());
                    tcqCalResult.setQmy(qm);
                    tcqCalResult = (CztCrsTcqCalResult) TranslateDecimalUtils.unUnitTranslate(tcqCalResult, UnitTranslate.class);
                    tcqResultRepository.save(tcqCalResult);
                } else {
                    //如果无填充墙， 计算结果默认为0
                    tcqCalResult.setQmy(0.0);
                }
            }
        }

        double qwz = 0.00;
        //计算剪力墙qwz
        if (PlatformObjectUtils.isNotEmpty(crsStoreyVo.getJlqList())) {
            for (RcpExcelSheet4Vo entity : crsStoreyVo.getJlqList()) {
                CztCrsJlqCalResult jlqCalResult = new CztCrsJlqCalResult();
                BeanUtil.copyPropertiesIgnoreEmpty(entity, jlqCalResult);
                jlqCalResult.setId(UUIDGenerator.getUUID());
                jlqCalResult.setEntiretyId(analyseVO.getEntiretyId());

                double fck = Src4Enum.getBycode(entity.getFck()) * 1000000;
                double aw = entity.getKzqWidth() * entity.getKzqHeight();
                double fyvk = Src4Enum.getBycode(entity.getRebarNum()) * 1000000;
                double h0 = entity.getKzqHeight();
                double s = entity.getS2();
                double temp = crsStoreyVo.getHjlq() * 0.5 / entity.getKzqHeight();
                //当>2.2 时取2.2 ,当小于1.5时候1.5;
                double lamda = (temp >= 2.2 ? 2.2 : temp) <= 1.5 ? 1.5 : (temp >= 2.2 ? 2.2 : temp);
                double qwy = 0.00;
                if (PlatformObjectUtils.isEmpty(entity.getAs())) {
                    qwy = (0.04 * fck * aw + 0.1 * entity.getJlqNu()) / (lamda - 0.5);
                } else {
                    qwy = (0.04 * fck * aw + 0.1 * entity.getJlqNu()) / (lamda - 0.5) + 0.8 * fyvk * entity.getAs() * h0 / s;
                }
                //单位转换
                jlqCalResult.setQwy(qwy);
                qwz += qwy;
                //单位反转换
                jlqCalResult = (CztCrsJlqCalResult) TranslateDecimalUtils.unUnitTranslate(jlqCalResult, UnitTranslate.class);
                jlqResultRepository.save(jlqCalResult);
            }
        }

        storeyCalResult.setQwz(qwz);
        storeyCalResult.setQmi(qmy);
        return storeyCalResult;
    }

    //计算地震剪力
    private List<CztCrsStoreyCalResult> calculateStorey(Map<Integer, List<CztCrsCalColumnResult>> storeyMap, Map<String, Object> paramStoreyMap) {
        List<CrsStoreyVo> paramStorey = (List) paramStoreyMap.get(FxfzConstants.storeyPam);
        List<CrsEntiretyParamVo> entiretyParamVos = (List) paramStoreyMap.get(FxfzConstants.entiretyPam);
        List<CztCrsStoreyCalResult> resultList = new ArrayList<>();
        double ge = 0.00;
        double sumGh = 0.00;
        List<String> ciIds = (List) paramStoreyMap.get(FxfzConstants.ckPam);
//        String ciIds = (String) paramStoreyMap.get(FxfzConstants.ckPam);
        double ciValue = 1.0;

        for (String ciId : ciIds) {
            List<CStructureCiEntity> cStructureCis = rcStructureRepository.getCStructureCi();
            for (CStructureCiEntity entity : cStructureCis) {
                if (ciId.equals(entity.getCcsrId())) {
                    ciValue = ciValue + entity.getConditionValue();
                }
            }
        }

        for (CrsStoreyVo storeyVo : paramStorey) {
            //砖填充墙钢筋混凝土框架结构的层间现有受剪承载力
            CztCrsStoreyCalResult crsStoreyCalResult = new CztCrsStoreyCalResult();
            try {
                crsStoreyCalResult = calculateQmy(storeyVo);
            } catch (Exception e) {
                e.printStackTrace();
            }

            int index = paramStorey.indexOf(storeyVo);
            double nu = 0.00;
            double qcz = 0.00;
            double qcz1 = 0.00;
            double qmz = 0.00;
            double qwz = 0.00;
            double mucyAndMlcy = 0.00;
            for (Map.Entry<Integer, List<CztCrsCalColumnResult>> entry : storeyMap.entrySet()) {
                if (entry.getKey().equals(storeyVo.getFloorNum())) {
                    for (CztCrsCalColumnResult columnResult : entry.getValue()) {
                        qcz1 += columnResult.getExtends1();
                        qcz += columnResult.getQcz();
                        mucyAndMlcy = mucyAndMlcy + columnResult.getMlcy() + columnResult.getMucy();
                        nu += columnResult.getNu();
                        storeyVo.setTrussSpacing(columnResult.getTrussSpacing());
                    }
                }
                storeyVo.setMucyAndMlcy(mucyAndMlcy);
                storeyVo.setNu(nu);
                storeyVo.setQcz1(qcz1);
                storeyVo.setQcz(qcz);
                storeyVo.setQmz(crsStoreyCalResult.getQmi());
                storeyVo.setQwz(crsStoreyCalResult.getQwz());
            }
            double gi = storeyVo.getBuildWidth() * storeyVo.getTrussSpacing() * storeyVo.getLiveLoad() * 1000;
            sumGh += gi * storeyVo.getHi();
            ge += gi;
            paramStorey.set(index, storeyVo);
        }
        //特征周期，用来计算结构基本自振周期T1的地震影响系数a1
        // TODO: 2024/4/2 取值有问题  已修改
        double tg = FxfzConstants.eigen[Src3Enum.getBycode(entiretyParamVos.get(0).getSc())][Src3Enum.getBycode(entiretyParamVos.get(0).getEqGroup())];
        //建筑物总高度
        double totleHeight = paramStorey.stream().mapToDouble(CrsStoreyVo::getFloorHeight).sum();
        //建筑物第i层离地面的高度
        double storeyHeight = 0.00;
        //
        for (CrsStoreyVo storeyVo : paramStorey) {
            storeyHeight = storeyVo.getHi();
            CztCrsStoreyCalResult storeyCalResult = new CztCrsStoreyCalResult();
            List<CztCrsMatrixCalResult> mcResultList = new ArrayList<>();
            BeanUtil.copyPropertiesIgnoreEmpty(storeyVo, storeyCalResult);
            if (PlatformObjectUtils.isEmpty(storeyVo.getCalId())) {
                storeyCalResult.setCalId(UUIDGenerator.getUUID());
            }
            storeyCalResult.setEntiretyId(analyseVO.getEntiretyId());
            //阻尼比如果是0.05
            //结构基本自振周期 之前可以用户输入，现在不让输入了。之前使用的楼长，现在使用的宽度。
            double t1 = 0.25 + 0.53 * 0.001 * Math.pow(totleHeight, 2) / getRootSign(storeyVo.getBuildWidth());
            double sigemaN = calculateCoeff(tg, t1);
            storeyCalResult.setSigemaN(sigemaN);
            storeyCalResult.setT1(t1);
            storeyCalResult.setNumber(analyseVO.getNumber());

            double a1 = 1.00;

            //曲线下降段的衰减指数
            double gama = 0.9;
            //直线下降段的下降调整系数
            double it1 = 0.02;
            //阻尼调整系数
            double it2 = 1.0;
            //正常情况下阻尼比都是0.05 ，如果不是的话回注明。
            if (PlatformObjectUtils.isNotEmpty(analyseVO.getDampRatio()) && analyseVO.getDampRatio() != 0.05) {
                gama = 0.9 + (0.05 - analyseVO.getDampRatio()) / (0.3 + 6 * analyseVO.getDampRatio());
                it1 = 0.02 + (0.05 - analyseVO.getDampRatio()) / (4 + 32 * analyseVO.getDampRatio());
                if (it1 < 0)
                    it1 = 0;
                it2 = 1 + (0.05 - analyseVO.getDampRatio()) / (0.08 + 1.6 * analyseVO.getDampRatio());
                if (it2 < 0.55)
                    it2 = 0.55;
            }
            for (int i = 5; i < analyseVO.getAmaxArr().length; i++) {
                CztCrsMatrixCalResult mcResult = new CztCrsMatrixCalResult();
                double value = analyseVO.getAmaxArr()[i];
                if (0 < t1 && t1 < 0.1) {
                    a1 = ((value - 0.45 * value) * 10) * t1 + 0.45 * value;
                } else if (t1 > 0.1 && t1 < tg) {
                    a1 = value;
                } else if (t1 > tg && t1 < 5 * tg) {
                    a1 = Math.pow(tg / t1, gama) * it2 * value;
                } else if (t1 > 5 * tg && t1 < 6.0) {
                    a1 = (it2 * Math.pow(0.2, gama) - it1 * (t1 - 5 * tg)) * value;
                }
                //如果建筑物总楼层为一层，不乘0.85
                double qek = (paramStorey.size() == 1 ? a1 * ge : 0.85 * a1 * ge);
                double gi = storeyVo.getBuildWidth() * storeyVo.getTrussSpacing() * storeyVo.getLiveLoad() * 1000;
                //不除pi  todo
                HashMap<String, Double> map = calculateSum(paramStorey, storeyVo.getFloorNum(), sigemaN, qek, sumGh);
                Double qmi = map.get("sumQmi");
                double qi = (map.get("qcz") + map.get("qmz") + 0.7 * map.get("qwz") / storeyVo.getNumberOfPieces()) / qmi;
                double ui = 0.00;
                if (qi > 0) {
                    ui = (BigDecimal.valueOf(ciValue).setScale(2, RoundingMode.HALF_UP).doubleValue()) * Math.exp(2.6 * (1 - qi)) / Math.sqrt(qi);
                }
                storeyCalResult.setGi(gi);
                storeyCalResult.setT1(t1);
                storeyCalResult.setSigemaN(sigemaN);
                mcResult.setA1(a1);
                mcResult.setCalId(UUIDGenerator.getUUID());
                mcResult.setEntiretyId(storeyCalResult.getEntiretyId());
                //破坏程度，根据类型不同判断方式也不同。
                String type = analyseVO.getStructureType();
                mcResult.setDamageCondition(getCondition(paramStorey, ui, type));
                mcResult.setNumber(storeyCalResult.getNumber());
                mcResult.setUi(ui);

                mcResult.setFloorNum(storeyCalResult.getFloorNum());
                mcResult.setSi(i + 1 + "度");
                mcResult.setQek(qek);
                mcResult.setQmi(map.get("qmi"));
                mcResult.setDelFlag("2");
                mcResult.setQi(qi);
                mcResult = (CztCrsMatrixCalResult) TranslateDecimalUtils.translate2De(mcResult, DoubleDecimal.class);
                mcResultList.add(mcResult);
                crsMatrixCalResultRepository.save(mcResult);
            }
            analyseVO.getMatrixResults().add(mcResultList);
            analyseVO.getMatrixResult().put(storeyCalResult.getFloorNum(), mcResultList);

            storeyCalResult = (CztCrsStoreyCalResult) TranslateDecimalUtils.translate2De(storeyCalResult, DoubleDecimal.class);
            storeyCalResult.setDelFlag("2");
            storeyCalResult = (CztCrsStoreyCalResult) TranslateDecimalUtils.unUnitTranslate(storeyCalResult, UnitTranslate.class);
            crsStoreyCalResultRespository.save(storeyCalResult);
            resultList.add(storeyCalResult);
        }
        return resultList;
    }

    /**
     * @param paramStorey
     * @param level       当前楼层
     * @return
     */
    private static HashMap<String, Double> calculateSum(List<CrsStoreyVo> paramStorey, int level, double sigemaN, double qek, double sumGh) {
        double sumQmi = 0.0;
        double qmi = 0.0;
        for (int i = level - 1; i < paramStorey.size(); i++) {
            double storeyHeight = paramStorey.get(i).getHi();
            double gi = paramStorey.get(i).getBuildWidth() * paramStorey.get(i).getTrussSpacing() * paramStorey.get(i).getLiveLoad() * 1000;
            sumQmi += gi * storeyHeight * (1 - sigemaN) * qek / sumGh;
        }
        double gi = paramStorey.get(level-1).getBuildWidth() * paramStorey.get(level-1).getTrussSpacing() * paramStorey.get(level-1).getLiveLoad() * 1000;
        qmi = gi * paramStorey.get(level-1).getHi() * (1 - sigemaN) * qek / sumGh;
        double qcz = paramStorey.get(level-1).getQcz1();
        double qmz = paramStorey.get(level-1).getQmz();
        double qwz = paramStorey.get(level-1).getQwz();
        HashMap<String, Double> map = new HashMap<>();
        map.put("qcz", qcz);
        map.put("qmz", qmz);
        map.put("qwz", qwz);
        map.put("sumQmi", sumQmi);
        map.put("qmi", qmi);
        return map;
    }

    private static double getRootSign(double n) {
        double l = -10000;
        double r = 10000;
        while (r - l > 1e-8) {
            double mid = (r + l) / 2;
            if (Math.pow(mid, 3) > n) {
                r = mid;
            } else {
                l = mid;
            }
        }
        return l;
    }

    /**
     * @param
     * @param type
     * @return
     */
    private String getCondition(List<CrsStoreyVo> storeyVos, double ui, String type) {
        String result = "";
        switch (type) {
            case "框架-剪力墙结构":
                //框剪结构需要用到q剪和q框
                //q框
                double sumq1 = 0.00;
                double sumq2 = 0.00;
                int floorNum = 0;
                for (CrsStoreyVo storeyVo : storeyVos) {
                    double qk = storeyVo.getQcz();
                    double pieces = storeyVo.getTrussSpacing();
                    //q剪
                    double qj = storeyVo.getQwz();
                    double q1 = qk / (qk + qj / pieces);
                    double q2 = (qj / pieces) / (qk + qj / pieces);
                    sumq1 += q1;
                    sumq2 += q2;
                    //获取最大层数
                    if (storeyVo.getFloorNum() > floorNum) {
                        floorNum = storeyVo.getFloorNum();
                    }
                }
                double perQ1 = sumq1 / floorNum;
                double perQ2 = sumq2 / floorNum;
                if (ui <= perQ1 + 0.3 * perQ2) {
                    result = "基本完好";
                } else if (ui > perQ1 + 0.3 * perQ2 && ui <= 3 * perQ1 + 1.5 * perQ2) {
                    result = "轻微破坏";
                } else if (ui > 3 * perQ1 + 1.5 * perQ2 && ui <= 6 * perQ1 + 3 * perQ2) {
                    result = "中等破坏";
                } else if (ui > 6 * perQ1 + 3 * perQ2 && ui <= 10 * perQ1 + 5 * perQ2) {
                    result = "严重破坏";
                } else if (ui > 10 * perQ1 + 5 * perQ2) {
                    result = "毁坏";
                }
                break;
            case "剪力墙结构":
                if (ui >= 0.3 && ui < 1) {
                    result = "基本完好";
                } else if (ui >= 1 && ui < 1.5) {
                    result = "轻微破坏";
                } else if (ui >= 1.5 && ui < 3) {
                    result = "中等破坏";
                } else if (ui >= 3 && ui < 5) {
                    result = "严重破坏";
                } else {
                    result = "毁坏";
                }
                break;
            case "框架结构":
                if (ui < 1) {
                    result = "基本完好";
                } else if (ui >= 1 && ui < 3) {
                    result = "轻微破坏";
                } else if (ui >= 3 && ui < 6) {
                    result = "中等破坏";
                } else if (ui >= 6 && ui < 10) {
                    result = "严重破坏";
                } else {
                    result = "毁坏";
                }
                break;
        }
        return result;
    }

    private Map<String, Object> prepareParam(Map<String, Object> paramMap) {
        //定义下数据来源，数据导入的还是页面上计算的。
        String dataType = "";
        //转换格式，否则从前端过来的数据会报错。
        List<CrsEntiretyParamVo> entiretyList = new ArrayList();
        for (Object object : (List) paramMap.get(FxfzConstants.entiretyPam)) {
            String jsonStr = JSON.toJSONString(object);
            CrsEntiretyParamVo entiretyParamVo = JSON.parseObject(jsonStr, CrsEntiretyParamVo.class);
            //如果是页面上计算的，需要将剪力墙/填充墙的参数手动放到层参数里。
            if (PlatformObjectUtils.isNotEmpty(entiretyParamVo.getDataType()) && "1".equals(entiretyParamVo.getDataType())) {
                dataType = "1";
            }
            analyseVO.setEntiretyId(PlatformObjectUtils.isEmpty(entiretyParamVo.getCalId()) ? UUIDGenerator.getUUID() : entiretyParamVo.getCalId());
            //需要先删除数据之前计算过的数据，防止重新计算的时候重复存;
            if (PlatformObjectUtils.isNotEmpty(entiretyParamVo.getCalId())) {
                srcAnaluseUtils.deleteByEntiretyId(analyseVO.getEntiretyId());
            }

            //模板上没有阻尼比，导入的统一都按照0.05计算。
            analyseVO.setDampRatio(entiretyParamVo.getDampRatio());
            analyseVO.setStructureType(entiretyParamVo.getStructureType1());
            double[] amaxArr = new double[10];
            amaxArr[5] = Src4Enum.getBycode("amax6") / 0.45;
            amaxArr[6] = Src4Enum.getBycode("amax7") / 0.45;
            amaxArr[7] = Src4Enum.getBycode("amax8") / 0.45;
            amaxArr[8] = Src4Enum.getBycode("amax9") / 0.45;
            amaxArr[9] = Src4Enum.getBycode("amax10") / 0.45;
            analyseVO.setAmaxArr(amaxArr);
            //ci
            ArrayList<String> ciIds = new ArrayList<>();
            CStructureCiEntity type1 = rcStructureRepository.getCStructureCiByCondition(entiretyParamVo.getCiType1(), CorrectionCiEnum.getByCode(entiretyParamVo.getCiType1Value()), entiretyParamVo.getCiType1Value());
            CStructureCiEntity type2 = rcStructureRepository.getCStructureCiByCondition(entiretyParamVo.getCiType2(), CorrectionCiEnum.getByCode(entiretyParamVo.getCiType2Value()), entiretyParamVo.getCiType2Value());
            CStructureCiEntity type3 = rcStructureRepository.getCStructureCiByCondition(entiretyParamVo.getCiType3(), CorrectionCiEnum.getByCode(entiretyParamVo.getCiType3Value()), entiretyParamVo.getCiType3Value());
            CStructureCiEntity type4 = rcStructureRepository.getCStructureCiByCondition(entiretyParamVo.getCiType4(), CorrectionCiEnum.getByCode(entiretyParamVo.getCiType4Value()), entiretyParamVo.getCiType4Value());
            ciIds.add(type1.getCcsrId());
            ciIds.add(type2.getCcsrId());
            ciIds.add(type3.getCcsrId());
            ciIds.add(type4.getCcsrId());
            paramMap.put(FxfzConstants.ckPam, ciIds);
            entiretyList.add(entiretyParamVo);
        }
        paramMap.put(FxfzConstants.entiretyPam, entiretyList);
        List<ColumnVO> columnList = new ArrayList();
        for (Object object : (List) paramMap.get(FxfzConstants.columnPam)) {
            String jsonStr = JSON.toJSONString(object);
            ColumnVO columnVO = JSON.parseObject(jsonStr, ColumnVO.class);
            //BeanUtil.copyPropertiesIgnoreEmpty(entiretyList.get(0), columnVO);
            //如果是前端输入的，需要讲梁参数重新放一下。
            if ("1".equals(dataType)) {
                CztCrsCalRoofbeamResult roofBeam1 = new CztCrsCalRoofbeamResult();
                BeanUtil.copyPropertiesIgnoreEmpty(columnVO, roofBeam1);
                if (PlatformObjectUtils.isNotEmpty(roofBeam1.getBeamNum())) {
                    columnVO.setRoofBeam(roofBeam1);
                }
            }
            RcpInformationEntity entity = new RcpInformationEntity();
            BeanUtil.copyPropertiesIgnoreEmpty(columnVO, entity);
            if (PlatformObjectUtils.isEmpty(entity.getCcpiId())) {
                entity.setCcpiId(UUIDGenerator.getUUID());
            }
            entity.setEntiretyId(analyseVO.getEntiretyId());
            rcpRepository.save(entity);
            columnVO.setCcpiId(entity.getCcpiId());
            //统一做单位转换 将mm转换成m
            columnVO = (ColumnVO) TranslateDecimalUtils.unitTranslate(columnVO, UnitTranslate.class);
            CztCrsCalRoofbeamResult roofBeam = columnVO.getRoofBeam();
            if (PlatformObjectUtils.isNotEmpty(roofBeam)) {
                roofBeam = (CztCrsCalRoofbeamResult) TranslateDecimalUtils.unitTranslate(roofBeam, UnitTranslate.class);
                columnVO.setRoofBeam(roofBeam);
            }
            columnList.add(columnVO);
        }

        List<CrsStoreyVo> storeys = new ArrayList();
        double totleH = 0.00;
        //将柱子按照楼层号分组
        Map<Integer, List<ColumnVO>> collect = columnList.stream().collect(Collectors.groupingBy(ColumnVO::getFloorNum));
        for (Object object : (List) paramMap.get(FxfzConstants.storeyPam)) {
            String jsonStr = JSON.toJSONString(object);
            CrsStoreyVo storeyVo = JSON.parseObject(jsonStr, CrsStoreyVo.class);
            //如果是页面上计算的，需要将剪力墙/填充墙的参数手动放到层参数里。
            if ("1".equals(dataType)) {
                List<RcpExcelSheet4Vo> jlqList = new ArrayList<>();
                for (Object o : (List) paramMap.get(FxfzConstants.jlqPam)) {
                    String str = JSON.toJSONString(o);
                    RcpExcelSheet4Vo rcpExcelSheet4Vo = JSON.parseObject(str, RcpExcelSheet4Vo.class);
                    if (rcpExcelSheet4Vo.getFloorNum().equals(storeyVo.getFloorNum())) {
                        jlqList.add(rcpExcelSheet4Vo);
                    }
                }
                List<RcpExcelSheet3Vo> tcqList = new ArrayList<>();
                for (Object o : (List) paramMap.get(FxfzConstants.tcqPam)) {
                    String str = JSON.toJSONString(o);
                    RcpExcelSheet3Vo rcpExcelSheet3Vo = JSON.parseObject(str, RcpExcelSheet3Vo.class);
                    if (rcpExcelSheet3Vo.getFloorNum().equals(storeyVo.getFloorNum())) {
                        tcqList.add(rcpExcelSheet3Vo);
                    }
                }
                storeyVo.setJlqList(jlqList);
                storeyVo.setTcqList(tcqList);
            }

            List<ColumnVO> columnVOS = collect.get((storeyVo.getFloorNum()));
            storeyVo.setColumnVOS(columnVOS);
            String result = columnVOS.stream()
                    .map(ColumnVO::getPillarCode)
                    .collect(Collectors.joining(","));
            storeyVo.setPillarCodes(result);

            totleH += storeyVo.getFloorHeight();
            storeyVo = (CrsStoreyVo) TranslateDecimalUtils.unitTranslate(storeyVo, UnitTranslate.class);
            if (PlatformObjectUtils.isNotEmpty(storeyVo.getTcqList())) {
                for (RcpExcelSheet3Vo tcq : storeyVo.getTcqList()) {
                    int i = storeyVo.getTcqList().indexOf(tcq);
                    tcq = (RcpExcelSheet3Vo) TranslateDecimalUtils.unitTranslate(tcq, UnitTranslate.class);
                    storeyVo.getTcqList().set(i, tcq);
                }
            }
            if (PlatformObjectUtils.isNotEmpty(storeyVo.getJlqList())) {
                for (RcpExcelSheet4Vo jlq : storeyVo.getJlqList()) {
                    int i = storeyVo.getJlqList().indexOf(jlq);
                    jlq = (RcpExcelSheet4Vo) TranslateDecimalUtils.unitTranslate(jlq, UnitTranslate.class);
                    storeyVo.getJlqList().set(i, jlq);
                }
            }
            storeys.add(storeyVo);
        }
        //获取每一层nValue 的值。以及每根柱子都Nl,Nu的值。
        double nValue = 0.00;
        //获取N 的方式变了，现在每层的N 都不相同，从当前层向上累加。
        for (CrsStoreyVo storeyVo : storeys) {
            double gn = 0.00;
            double jlqGn = 0.00;
            double Hi = 0.00;
            for (int i = storeyVo.getFloorNum() - 1; i < storeys.size(); i++) {
                double gi = storeys.get(i).getBuildWidth() * storeys.get(i).getTrussSpacing() * storeys.get(i).getLiveLoad();
                gn += gi;
                //剪力墙
                for (RcpExcelSheet4Vo vo : storeys.get(i).getJlqList()) {
                    jlqGn += vo.getKzqHeight() * storeys.get(i).getTrussSpacing() * storeys.get(i).getLiveLoad();
                }
            }
            for (int i = 0; i < storeyVo.getFloorNum(); i++) {
                //第i层距离地面的高度。
                Hi += storeys.get(i).getFloorHeight();
            }
            //例如，共计5层时，计算第3层时候，总楼层-2层以下的高度，或者第3层+第4层+第5层高
            double hjlq = totleH;
            for (int i = 1; i < storeyVo.getFloorNum(); i++) {
                hjlq -= storeys.get(i - 1).getFloorHeight();
            }
            storeyVo.setHjlq(hjlq);
            storeyVo.setHi(Hi);
            storeyVo.setGn(gn);
            storeyVo.setJlqGn(jlqGn);
        }
        //先按照层来分了组
        Map<Integer, List<ColumnVO>> columnMap = columnList.stream().collect(Collectors.groupingBy(ColumnVO::getFloorNum));
        columnMap.forEach((key, value) -> {
            List<ColumnVO> columnVOS = columnMap.get(key);
            //将所有的上梁组成list，然后下边的循环里计算l的时候需要使用
            List<CztCrsCalRoofbeamResult> roofbeams = new ArrayList<>();

            for (ColumnVO entity : columnVOS) {
                roofbeams = columnVOS.stream().map(ColumnVO::getRoofBeam).collect(Collectors.toList());
                //去掉空元素。
                roofbeams = roofbeams.stream().filter(PlatformObjectUtils::isNotEmpty).collect(Collectors.toList());
                //计算l1
                double l1 = 0.00;
                //有的柱子是没有梁的。比如说三根柱子 A B C , 一共两根梁，A-B和 B-C 那C柱子就没有梁。
                if (PlatformObjectUtils.isNotEmpty(entity.getRoofBeam())) {
                    l1 = entity.getRoofBeam().getBeamSpan();
                }
                //如果没有梁，那就需要找他上一根柱子的梁。
                else {
                    List<CztCrsCalRoofbeamResult> roofbeamResults = roofbeams.stream().filter(item -> item.getBeamNum().contains("-" + entity.getPillarCode())).collect(Collectors.toList());
                    //默认只有一个。
                    if (PlatformObjectUtils.isNotEmpty(roofbeamResults)) {
                        l1 = roofbeamResults.get(0).getBeamSpan();
                    }
                }
                //递归-找到该柱子相关的所有的梁;
                List<CztCrsCalRoofbeamResult> roofbeamResults = new ArrayList<>();
                List<CztCrsCalRoofbeamResult> collect1 = roofbeams.stream().filter(beam -> beam.getBeamNum().contains("-" + entity.getPillarCode())).filter(beam -> PlatformObjectUtils.isNotEmpty(beam)).collect(Collectors.toList());
                List<CztCrsCalRoofbeamResult> collect2 = roofbeams.stream().filter(roofbeam -> roofbeam.getBeamNum().contains("-" + entity.getPillarCode()) || roofbeam.getBeamNum().contains(entity.getPillarCode() + "-")).collect(Collectors.toList());
                //如果是中柱
                if (PlatformObjectUtils.isNotEmpty(collect2) && collect2.size() > 1) {
                    l1 = collect2.stream().mapToDouble(CztCrsCalRoofbeamResult::getBeamSpan).sum();
                }
                roofbeamResults = findRoofbeams(entity.getPillarCode(), roofbeams, roofbeamResults, collect1);
                Double beamSpan = 0.00;
                if (PlatformObjectUtils.isNotEmpty(roofbeamResults)) {
                    //粱跨度
                    beamSpan = roofbeamResults.stream().mapToDouble(CztCrsCalRoofbeamResult::getBeamSpan).sum();
                }
                //计算每根柱子的Nu和Nl;
                double nu = 0.00;
                double jlqNu = 0.00;
                double nl = 0.00;
                List<CrsStoreyVo> storeyVos = storeys.stream().filter(item -> item.getFloorNum() == entity.getFloorNum()).collect(Collectors.toList());
                //默认每个建筑每一层只有一条数据
                double gn = 0.00;
                if (PlatformObjectUtils.isNotEmpty(storeyVos)) {
                    gn = storeyVos.get(0).getGn();
                    //剪力墙
                    for (RcpExcelSheet4Vo vo : storeyVos.get(0).getJlqList()) {
                        jlqNu = storeyVos.get(0).getJlqGn();
                        vo.setJlqNu(jlqNu * 1000);
                    }
                }
                double qczNu = gn * 0.5 * l1 / beamSpan;
                nu = gn * 0.5 * l1 / beamSpan - 12.5 * entity.getPillarSectionWidth() * entity.getPillarSectionHeight() * entity.getPillarHeight();
                nl = gn * 0.5 * l1 / beamSpan + 12.5 * entity.getPillarSectionWidth() * entity.getPillarSectionHeight() * entity.getPillarHeight();
//                nu = gn * l1 / (beamSpan * 2) - 12.5 * entity.getPillarSectionWidth() * entity.getPillarSectionHeight() * entity.getPillarHeight();
//                nl = gn * l1 / (beamSpan * 2) + 12.5 * entity.getPillarSectionWidth() * entity.getPillarSectionHeight() * entity.getPillarHeight();
                entity.setNu(nu * 1000);
                entity.setNl(nl * 1000);
                entity.setQczNu(qczNu * 1000);
                entity.setJlqNu(jlqNu * 1000);
            }
        });
        //循环每一层，得到每一层的N ;
        for (CrsStoreyVo storeyVo : storeys) {
            //得到所有当前层以上的柱子，再将柱子的nu相加得到nValue的值；
            List<ColumnVO> columnVOS = columnList.stream().filter(item -> item.getFloorNum() >= storeyVo.getFloorNum()).collect(Collectors.toList());
            nValue = columnVOS.stream().mapToDouble(ColumnVO::getNu).sum();
            storeyVo.setNValue(nValue);
        }
        paramMap.put(FxfzConstants.columnPam, columnList);
        paramMap.put(FxfzConstants.storeyPam, storeys);
        // TODO: 2023/12/19 这个值前端没传。 重新计算有问题。crsEntiretyCis没存
        String recalculate = (String) paramMap.get("calculate_ornot");
        List<CztCrsEntiretyCi> crsEntiretyCis = crsEntiretyCiRepository.findByEntiretyId(analyseVO.getEntiretyId());
        if (PlatformObjectUtils.isNotEmpty(crsEntiretyCis)) {
            if (PlatformObjectUtils.isEmpty(recalculate)) {
                crsEntiretyCiRepository.deleteByEntiretyIdAndDelFlag(analyseVO.getEntiretyId(), "0");
                for (Object object : (List) paramMap.get(FxfzConstants.ckPam)) {
                    String jsonStr = JSON.toJSONString(object);
                    String ciId = JSON.parseObject(jsonStr, String.class);
                    CztCrsEntiretyCi entiretyCi = new CztCrsEntiretyCi();
                    entiretyCi.setId(UUIDGenerator.getUUID());
                    entiretyCi.setCreateUser(PlatformSessionUtils.getUserId());
                    entiretyCi.setCiId(ciId);
                    entiretyCi.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    entiretyCi.setEntiretyId(analyseVO.getEntiretyId());
                    entiretyCi.setDelFlag("0");
                    crsEntiretyCiRepository.save(entiretyCi);
                }
            } else {
                for (Object object : (List) paramMap.get(FxfzConstants.ckPam)) {
                    String jsonStr = JSON.toJSONString(object);
                    String ciId = JSON.parseObject(jsonStr, String.class);
                    List<CStructureCiEntity> cStructureCis = rcStructureRepository.getCStructureCi();
                    CStructureCiEntity cstructureCiEntity = rcStructureRepository.getCstructureCiById(ciId);
                    if (!cStructureCis.contains(cstructureCiEntity)) {
                        crsEntiretyCiRepository.deleteByEntiretyIdAndDelFlagAndCiId(analyseVO.getEntiretyId(), "0", ciId);
                    }
                }
            }
        }

        return paramMap;
    }

    /**
     * 递归找所有跟该柱子相关的梁
     *
     * @param pillarCode      柱编号
     * @param roofbeamResults 该层所有的上梁
     * @return
     */
    private List<CztCrsCalRoofbeamResult> findRoofbeams(String pillarCode, List<CztCrsCalRoofbeamResult> roofbeamResults, List<CztCrsCalRoofbeamResult> results, List<CztCrsCalRoofbeamResult> rejectBeams) {
        //先找以柱编号开头的梁，然后迭代往下找所有的梁
        List<CztCrsCalRoofbeamResult> collect = roofbeamResults.stream().filter(entity -> entity.getBeamNum().contains(pillarCode + "-")).filter(entity -> PlatformObjectUtils.isNotEmpty(entity)).collect(Collectors.toList());
        //如果存在的话就顺着往下找,如果是只有一个那还好，如果是两个这样就不行了。
        if (PlatformObjectUtils.isNotEmpty(collect)) {
            if (collect.size() == 1) {
                String[] split = collect.get(0).getBeamNum().split("-");
                String nextPillarCode = split[1];
                roofbeamResults.remove(collect.get(0));
                results.add(collect.get(0));
                return findRoofbeams(nextPillarCode, roofbeamResults, results, rejectBeams);
            }
        }
        //如果正向找不到了，那就开始反向找
        else if (PlatformObjectUtils.isNotEmpty(rejectBeams)) {
            String[] split = rejectBeams.get(0).getBeamNum().split("-");
            String lastPillacode = split[0];
            results.add(rejectBeams.get(0));
            roofbeamResults.remove(rejectBeams.get(0));
            rejectBeams = roofbeamResults.stream().filter(beam -> beam.getBeamNum().contains("-" + lastPillacode)).filter(beam -> PlatformObjectUtils.isNotEmpty(beam)).collect(Collectors.toList());
            return findRoofbeams(lastPillacode, roofbeamResults, results, rejectBeams);
        }
        return results;

    }

    //计算矩形框架柱层间屈服剪力 Qcz方法
    private CztCrsCalColumnResult calculateQcz(ColumnVO lastEntity, ColumnVO entity, ColumnVO nextEntity, List<CrsStoreyVo> storeyVos) {
        CztCrsCalColumnResult columnResult = new CztCrsCalColumnResult();
        columnResult.setCalId(UUIDGenerator.getUUID());
        columnResult.setEntiretyId(analyseVO.getEntiretyId());
        BeanUtil.copyPropertiesIgnoreEmpty(entity, columnResult);
        //柱子截面高
        double h = entity.getPillarSectionHeight();
        //柱的截面宽 输入单位为mm 需转换成m
        double b = entity.getPillarSectionWidth();
        //fck 钢筋混凝土强度等级 输入的是Code 需要转换成Value;
        String fckCode = entity.getFck();
        Double fcmk = SrcFmckEnum.getBycode(fckCode) * 1000000;
        Double fck = Src4Enum.getBycode(fckCode) * 1000000;

        double hn = entity.getPillarHeight();
        //柱验算方向的有效高,跟柱的截面高有什么关系？
        double h0 = entity.getPillarSectionHeight() - entity.getDistance();
        //箍筋抗拉强度标准值
        double fykUp = Src4Enum.getBycode(entity.getStirrupUpNum()) * 1000000;
        double fykDown = Src4Enum.getBycode(entity.getStirrupDownNum()) * 1000000;
        double fyk = Src4Enum.getBycode(entity.getStirrupNum()) * 1000000;
        //受压筋合理点距受压边缘的距离  as
        double distance = entity.getDistance();
        //柱箍筋截面积Asv  (mm^2)
        double asv = entity.getSectionalArea();
        //columnResult.setNl(entity.getNl());
        // 求N n层Nu之和 (N的值在整个建筑中是个定值)
//        double ncz =
        // 框架柱的计算剪跨比 λ 取λ = Hn/2h0 ，当 λ<=1 时取1，λ>=3时取3   *500?
//        double temp = hn * 500 / (2*h0);
        double temp = hn / (2 * h0);
        double lamda = (temp >= 3 ? 3 : temp) <= 1 ? 1 : (temp >= 3 ? 3 : temp);
        columnResult.setLambda(lamda);
        //三种情况计算Mcy 1、强梁弱柱型 2、对称配筋矩形截面偏压柱 3、非强梁弱柱型
        //强梁弱柱型  需要先判断N 的值
        double threshVal = 0.4 * b * h * fck;
        double qczm = 0.00;
        double mucy = 0.00;
        double mlcy = 0.00;
        //强梁弱柱的。
        double muz = 0.00;
        double mlz = 0.00;
        //对称配筋
        double mucys = 0.00;
        double mlcys = 0.00;
        //强柱弱梁
        double mucyb = 0.00;
        double mlcyb = 0.00;

        double nu = entity.getNu();
        double nl = entity.getNl();
        double bk = 0.0;
        double qcz = 0.0;
        Map<Integer, List<CrsStoreyVo>> collect = storeyVos.stream().collect(Collectors.groupingBy(CrsStoreyVo::getFloorNum));
        List<CrsStoreyVo> storeyVos1 = collect.get(entity.getFloorNum());
        /**
         *  //增加判断，柱上端受压区纵向钢筋面积As'  和   柱上端受拉区纵向钢筋面积As 是否相等；
         *  柱下端受压区纵向钢筋面积As'  和  柱下端受拉区纵向钢筋面积As  是否相等。
         *  如柱上端相等，则柱上端用对称，柱下端相等用柱下端。
         *  若相等则  直接计算【（2）对称配筋矩形截面偏压柱】；若不相等则【（1）当框架为强梁弱柱型框架柱时】【（3）非强梁弱柱型框】都计算，并采取最小M值，Mmin
         */
        //先判断上端
        if (entity.getSectionalUpArea1().toString().equals(entity.getSectionalUpArea2().toString())) {
            double as = entity.getSectionalUpArea2();
            double as1 = entity.getDistance2();
            if (entity.getStirrupUpNum().contains("HPB")) {
                bk = 0.6;
            } else {
                bk = 0.55;
            }

            //对称配筋
            // fcmk 和 fck 是一个值
            threshVal = bk * fcmk * b * h0;
            if (entity.getNu() <= threshVal) {
                mucy = fykUp * as * (h0 - as1) + 0.5 * nu * h * ((1 - nu) / (fcmk * b * h));
                mucys = mucy;
//                if (entity.getSectionalDownArea2().toString().equals(entity.getSectionalDownArea1().toString())) {
//                    mlcy = fykDown * as * (h0 - as1) + 0.5 * nl * h * ((1 - nl) / (fcmk * b * h));
//                    mlcys = mlcy;
//                }
            } else {
                double parameter = ((bk - 0.8) * nu - bk * fykUp * as) / ((bk - 0.8) * fcmk * b * h0 - fykUp * as);
                mucy = fykUp * as * (h0 - as1) + parameter * (1 - 0.5 * parameter) * fcmk * b * Math.pow(h0, 2) - nu * (0.5 * h - as1);
                mucys = mucy;
//                parameter = ((bk - 0.8) * nl - bk * fykUp * as) / ((bk - 0.8) * fcmk * b * h0 - fykUp * as);
//                if (entity.getSectionalDownArea1().toString().equals(entity.getSectionalDownArea2().toString())) {
//                    mlcy = fykUp * as * (h0 - as1) + parameter * (1 - 0.5 * parameter) * fcmk * b * Math.pow(h0, 2) - nl * (0.5 * h - as1);
//                    mlcys = mlcy;
//                }
            }

            if (entity.getNl() <= threshVal) {
                if (entity.getSectionalDownArea2().toString().equals(entity.getSectionalDownArea1().toString())) {
                    mlcy = fykDown * as * (h0 - as1) + 0.5 * nl * h * (1 - nl / (fcmk * b * h));
                    mlcys = mlcy;
                }
            } else {
                double parameter = ((bk - 0.8) * nl - bk * fykUp * as) / ((bk - 0.8) * fcmk * b * h0 - fykUp * as);
                if (entity.getSectionalDownArea1().toString().equals(entity.getSectionalDownArea2().toString())) {
                    mlcy = fykUp * as * (h0 - as1) + parameter * (1 - 0.5 * parameter) * fcmk * b * Math.pow(h0, 2) - nl * (0.5 * h - as1);
                    mlcys = mlcy;
                }
            }
            //如果柱下端是对称配筋
            if (!entity.getSectionalDownArea2().toString().equals(entity.getSectionalDownArea1().toString())) {
                Map<String, Double> tempMap = calculateMucy(entity, lastEntity, nextEntity, storeyVos, "2");
                mlz = tempMap.get("mlz");
                mlcy = tempMap.get("mlcy");
                mlcyb = tempMap.get("mlcyb");
            }
            Map<String, Double> tempMap = calculateMucy(entity, lastEntity, nextEntity, storeyVos, "0");
            mucy = tempMap.get("mucyb");
            if (entity.getFloorNum() != 1) {
                mlcy = tempMap.get("mlcyb");
            }
        }
        //如果柱上端不是对称配筋，看下端是否为对称配筋。
        else {
            //如果柱下端是对称配筋
            if (entity.getSectionalDownArea2().toString().equals(entity.getSectionalDownArea1().toString())) {
                double as = entity.getSectionalDownArea2();
                double as1 = entity.getDistance();
                if (entity.getStirrupDownNum().contains("HPB")) {
                    bk = 0.6;
                } else {
                    bk = 0.55;
                }
                threshVal = bk * fcmk * b * h0;
                if (storeyVos1.get(0).getNValue() <= threshVal) {
                    mlcy = fykDown * as * (h0 - as1) + 0.5 * nl * h * ((1 - nl) / (fcmk * b * h));
                    mlcys = mlcy;
                } else {
                    double parameter = ((bk - 0.8) * nu - bk * fyk * as) / ((bk - 0.8) * fcmk * b * h0 - fyk * as);
                    mlcy = fyk * as * (h0 * as1) + parameter * (1 - 0.5 * parameter) * fcmk * b * Math.pow(h0, 2) - nl * (0.5 * h - as1);
                    mlcys = mlcy;
                }
                Map<String, Double> tempMap = calculateMucy(entity, lastEntity, nextEntity, storeyVos, "1");
                mucy = tempMap.get("mucy");
                muz = tempMap.get("muz");
                mucyb = tempMap.get("mucyb");
            } else {
                Map<String, Double> tempMap = calculateMucy(entity, lastEntity, nextEntity, storeyVos, "0");
                mucy = tempMap.get("mucy");
                muz = tempMap.get("muz");
                mlz = tempMap.get("mlz");
                mlcy = tempMap.get("mlcy");
                mlcyb = tempMap.get("mlcyb");
                mucyb = tempMap.get("mucyb");
            }
        }
        qczm = (mucy + mlcy) / hn;
        double qczn = 0.16 * fck * b * h0 / (lamda + 1.5) + (fyk * asv * h0) / entity.getSpacing() + 0.056 * entity.getQczNu();
        columnResult.setMucy(mucy);
        columnResult.setMlcy(mlcy);
        columnResult.setMuz(muz);
        columnResult.setMlz(mlz);
        columnResult.setQczM(qczm);
        columnResult.setQczN(qczn);
        columnResult.setMucyb(mucyb);
        columnResult.setMlcyb(mlcyb);
        columnResult.setMucys(mucys);
        columnResult.setMlcys(mlcys);
        columnResult.setQcz(qczm > qczn ? qczn : qczm);
        double qcz1 = columnResult.getQcz();
        for (RcpExcelSheet3Vo rcpExcelSheet3Vo : storeyVos1.get(0).getTcqList()) {
            if (rcpExcelSheet3Vo.getTcpNum().contains(entity.getPillarCode())) {
                if (PlatformObjectUtils.isNotEmpty(rcpExcelSheet3Vo.getBwCategory())) {
                    qcz1 = columnResult.getQcz() * 0.7;
                }
            }
        }
        // todo  这里先加到冗余字段里，
        columnResult.setExtends1(qcz1);
        System.out.println("qcz1 = " + qcz1);
        columnResult.setNu(nu);
        columnResult.setFloorNum(entity.getFloorNum());
        columnResult.setPillarCode(entity.getPillarCode());
        columnResult.setNumber(analyseVO.getNumber());
        if (PlatformObjectUtils.isEmpty(analyseVO.getMcyMap()) || PlatformObjectUtils.isEmpty(analyseVO.getMcyMap().get(columnResult.getFloorNum()))) {
            analyseVO.getMcyMap().put(columnResult.getFloorNum(), mucy + mlcy);
        } else {
            analyseVO.getMcyMap().put(columnResult.getFloorNum(), analyseVO.getMcyMap().get(columnResult.getFloorNum()) + mucy + mlcy);
        }
        return columnResult;
    }

    /**
     * @param entity     柱子参数
     * @param lastEntity 下一层的柱子
     * @param nextEntity 上一层的柱子
     * @param storeyVos  层
     * @param type       柱子的上端还是下端。1是上端。2是下端
     * @return
     */

    private Map<String, Double> calculateMucy(ColumnVO entity, ColumnVO lastEntity, ColumnVO nextEntity, List<CrsStoreyVo> storeyVos, String type) {
        CztCrsCalColumnResult columnResult = new CztCrsCalColumnResult();
        columnResult.setEntiretyId(analyseVO.getEntiretyId());
        BeanUtil.copyPropertiesIgnoreEmpty(entity, columnResult);
        //柱子截面高
        double h = entity.getPillarSectionHeight();
        //柱的截面宽 输入单位为mm 需转换成m
        double b = entity.getPillarSectionWidth();
        //fck 钢筋混凝土强度等级 输入的是Code 需要转换成Value;
        String fckCode = entity.getFck();
        //转换成KN/m2 ;
        Double fck = Src4Enum.getBycode(fckCode) * 1000000;

        double hn = entity.getPillarHeight();
        //柱验算方向的有效高,跟柱的截面高有什么关系？
        double h0 = entity.getPillarSectionHeight();
        //箍筋抗拉强度标准值
        double fyk = Src4Enum.getBycode(entity.getStirrupNum()) * 1000000;
        // 框架柱的计算剪跨比 λ 取λ = Hn/2h0 ，当 λ<=1 时取1，λ>=3时取3
        double temp = hn / (2 * h0);
        double lamda = (temp >= 3 ? 3 : temp) <= 1 ? 1 : (temp >= 3 ? 3 : temp);
        columnResult.setLambda(lamda);
        //三种情况计算Mcy 1、强梁弱柱型 2、对称配筋矩形截面偏压柱 3、非强梁弱柱型
        //强梁弱柱型  需要先判断N 的值
        //需要计算柱上端的nmax和nmin 以及柱下端的nmax 和 nmin 单位是N;
        double nUpMax = b * h * fck + (entity.getSectionalUpArea1() + entity.getSectionalUpArea2()) * Src4Enum.getBycode(entity.getStirrupUpNum());
        double nUpMin = Src4Enum.getBycode(entity.getStirrupUpNum()) * (entity.getSectionalUpArea1() + entity.getSectionalUpArea2());
        double nDownMax = b * h * fck + (entity.getSectionalDownArea1() + entity.getSectionalDownArea2()) * Src4Enum.getBycode(entity.getStirrupDownNum());
        double nDownMin = Src4Enum.getBycode(entity.getStirrupDownNum()) * (entity.getSectionalDownArea1() + entity.getSectionalDownArea2());
        double threshVal = 0.4 * b * h * fck;
        double mzu;
        double mzl = 0.00;
        double mucy = 0.00;
        double mlcy = 0.00;
        double mucyb = 0.00;
        double mlcyb = 0.00;
        double nu = entity.getNu();
        double nl = entity.getNl();
        double asUp2 = entity.getSectionalDownArea2();
        double asDown2 = entity.getSectionalDownArea2();

        //强梁弱柱型
        if (nUpMax >= nu && nu > threshVal) {
            mzu = (0.8 * asUp2 * fyk * h + 0.12 * b * Math.sqrt(h) * fck) * (nUpMax - nu) / (nUpMax - threshVal);
            // TODO: 2023/12/19 直接判断type就行了。
            if (entity.getSectionalDownArea2() != entity.getSectionalDownArea1()) {
                mzl = (0.8 * asDown2 * fyk * h + 0.12 * b * Math.sqrt(h) * fck) * (nDownMax - nl) / (nDownMax - threshVal);
            }
        } else if (threshVal >= nu && nu > 0) {
            mzu = 0.8 * asUp2 * fyk * h + 0.5 * nu * h * (1 - nu / (b * h * fck));
            if (entity.getSectionalDownArea2() != entity.getSectionalDownArea1()) {
                mzl = 0.8 * asDown2 * fyk * h + 0.5 * nu * h * (1 - nl / (b * h * fck));
            }
        } else if (0 > nu && nu > nUpMin) {
            mzu = 0.8 * asUp2 * fyk * h + 0.4 * nu * h;
            if (entity.getSectionalDownArea1() != entity.getSectionalDownArea2()) {
                mzl = 0.8 * asDown2 * fyk * h + 0.4 * nl * h;
            }
        } else {
            throw new ParamException("参数值异常，请检查输入的参数值！");
        }
        double ki = 0.00;
        //ki+1
        double nextKi = 0.00;
        //ki-1
        double lastKi = 0.00;
        double mlby = 0.00;
        double muby = 0.00;
        CztCrsCalRoofbeamResult beam = entity.getRoofBeam();
        //校验放到导入或者前端填写的时候，计算这里默认都不为空。
        //SrcAnaluseUtils.beamParamVerification(beam, entity.getPillarPosition());
        //先算muby 和 mlby 计算的时候需要判断柱子的位置以及楼层;
        String position = FxfzConstants.SidePillar;
        Integer floorNum = entity.getFloorNum();
        //最终的计算muby 的AS 的值。
        Double asUResult = 0.00;
        //最终计算mlby 的AS 的值；
        Double asLResult = 0.00;
        Map<Integer, List<CrsStoreyVo>> storeyMap = storeyVos.stream().collect(Collectors.groupingBy(CrsStoreyVo::getFloorNum));
        List<CrsStoreyVo> storeyVosList = storeyMap.get(entity.getFloorNum());
        CrsStoreyVo crsStoreyVo = storeyVosList.get(0);
        //得到该层所有的梁。
        List<CztCrsCalRoofbeamResult> roofbeamResults = crsStoreyVo.getRoofbeamResults();
        roofbeamResults = roofbeamResults.stream().filter(beam1 -> PlatformObjectUtils.isNotEmpty(beam1)).collect(Collectors.toList());
        List<CztCrsCalRoofbeamResult> collect2 = roofbeamResults.stream().filter(roofbeam -> roofbeam.getBeamNum().contains("-" + entity.getPillarCode()) || roofbeam.getBeamNum().contains(entity.getPillarCode() + "-")).collect(Collectors.toList());
        if (PlatformObjectUtils.isNotEmpty(collect2) && collect2.size() > 1) {
            position = FxfzConstants.MidPillar;
        }
        //得到该层所有的柱子
        List<ColumnVO> columnVOS = crsStoreyVo.getColumnVOS();
        //如果是底层;
        if (floorNum == 1) {
            //如果是边柱
            asLResult = entity.getSectionalDownArea1() > entity.getSectionalDownArea2() ? entity.getSectionalDownArea2() : entity.getSectionalDownArea1();
            if (position.equals(FxfzConstants.SidePillar)) {
                //通过判断该柱子是否有梁来判断是否为左边柱。默认左边柱是有梁的。右边柱没梁；左边柱取梁的左端
                if (PlatformObjectUtils.isNotEmpty(entity.getRoofBeam())) {
                    CztCrsCalRoofbeamResult roofbeamResult = entity.getRoofBeam();
                    asUResult = roofbeamResult.getLeftAsPull() >= roofbeamResult.getLeftAsPush() ? roofbeamResult.getLeftAsPush() : roofbeamResult.getLeftAsPull();
                    fyk = Src4Enum.getBycode(roofbeamResult.getBeamStirrupNum()) * 1000000;
                    //如果是底层左边柱，那就应该是i2 ;
                    muby = 0.9 * asUResult * fyk * roofbeamResult.getBeamLeftHeigth();
                    mlby = 0.9 * asLResult * fyk * roofbeamResult.getBeamLeftHeigth();
//                    muby = 0.9 * asLResult * fyk * roofbeamResult.getBeamLeftHeigth();
                } else {
                    //得到右边柱对应的梁。
                    List<CztCrsCalRoofbeamResult> collect = roofbeamResults.stream().filter(item -> item.getBeamNum().contains("-" + entity.getPillarCode())).collect(Collectors.toList());
                    asUResult = collect.get(0).getRigthAsPull() <= collect.get(0).getRigthAsPush() ? collect.get(0).getRigthAsPull() : collect.get(0).getRigthAsPush();
                    fyk = Src4Enum.getBycode(collect.get(0).getBeamStirrupNum()) * 1000000;
                    //底层右边柱只有i1 ;
                    //先找前边的柱子
                    List<ColumnVO> collect1 = columnVOS.stream().filter(columnVO -> columnVO.getPillarCode().equals(collect.get(0).getBeamNum().split("-")[0])).collect(Collectors.toList());
                    muby = 0.9 * asUResult * fyk * collect.get(0).getBeamRightHeight();
                    mlby = 0.9 * asLResult * fyk * collect.get(0).getBeamRightHeight();
//                    muby = 0.9 * asLResult * fyk * collect.get(0).getBeamRightHeight();
                }
            }
            //如果是底层中柱。
            else {
                //还是需要取前一根柱子的梁右端 ；
                CztCrsCalRoofbeamResult roofbeam1 = getRoofbeam(entity, roofbeamResults);
                CztCrsCalRoofbeamResult roofbeam2 = entity.getRoofBeam();
                Double tem1 = roofbeam1.getRigthAsPull() + roofbeam2.getLeftAsPull();
                Double tem2 = roofbeam1.getRigthAsPush() + roofbeam2.getLeftAsPush();
                //两个取较小值
                asUResult = tem1 > tem2 ? tem2 : tem1;
                fyk = Src4Enum.getBycode(roofbeam1.getBeamStirrupNum()) * 1000000;
                muby = 0.9 * asUResult * fyk * roofbeam1.getBeamRightHeight();
                mlby = 0.9 * asLResult * fyk * roofbeam1.getBeamRightHeight();
//                muby = 0.9 * asLResult * fyk * roofbeam1.getBeamRightHeight();
//                fyk = Src4Enum.getBycode(roofbeam2.getBeamStirrupNum());
//                muby += 0.9 * asUResult * fyk * roofbeam2.getBeamLeftHeigth();
//                mlby += 0.9 * asLResult * fyk * roofbeam2.getBeamLeftHeigth();
            }
        }
        //对于一般楼层 ；
        else {
            //得到下一层
            CrsStoreyVo lastCrsStroey = new CrsStoreyVo();
            List<CrsStoreyVo> lastCrsStroreys = storeyMap.get(entity.getFloorNum() - 1);
            if (PlatformObjectUtils.isNotEmpty(lastCrsStroreys)) {
                lastCrsStroey = lastCrsStroreys.get(0);
            }
            List<ColumnVO> lastColumnVOS = lastCrsStroey.getColumnVOS();
            //如果是边柱
            if (position.equals(FxfzConstants.SidePillar)) {
                if (PlatformObjectUtils.isNotEmpty(entity.getRoofBeam())) {
                    asUResult = entity.getRoofBeam().getLeftAsPull() > entity.getRoofBeam().getLeftAsPush() ? entity.getRoofBeam().getLeftAsPush() : entity.getRoofBeam().getLeftAsPull();
                    CztCrsCalRoofbeamResult roofbeamResult = lastEntity.getRoofBeam();
                    fyk = Src4Enum.getBycode(roofbeamResult.getBeamStirrupNum()) * 1000000;
                    asLResult = lastEntity.getRoofBeam().getLeftAsPull() > lastEntity.getRoofBeam().getLeftAsPush() ? lastEntity.getRoofBeam().getLeftAsPush() : lastEntity.getRoofBeam().getLeftAsPull();
                    muby = 0.9 * asUResult * fyk * roofbeamResult.getBeamLeftHeigth();
                    mlby = 0.9 * asLResult * fyk * roofbeamResult.getBeamLeftHeigth();
                }
                //右边柱
                else {
                    List<CrsStoreyVo> storeyVos1 = storeyMap.get(entity.getFloorNum() - 1);
                    List<CztCrsCalRoofbeamResult> roofbeamResults1 = storeyVos1.get(0).getRoofbeamResults();
                    CztCrsCalRoofbeamResult roofbeamResult = getRoofbeam(lastEntity, roofbeamResults1);
                    asLResult = roofbeamResult.getRigthAsPull() > roofbeamResult.getRigthAsPush() ? roofbeamResult.getRigthAsPush() : roofbeamResult.getRigthAsPull();
                    //梁2 计算asUResult
                    //得到右边柱对应的梁。
                    List<CztCrsCalRoofbeamResult> collect1 = roofbeamResults.stream().filter(item -> item.getBeamNum().contains("-" + entity.getPillarCode())).collect(Collectors.toList());
                    asUResult = collect1.get(0).getRigthAsPull() <= collect1.get(0).getRigthAsPush() ? collect1.get(0).getRigthAsPull() : collect1.get(0).getRigthAsPush();
                    fyk = Src4Enum.getBycode(roofbeamResult.getBeamStirrupNum()) * 1000000;
                    muby = 0.9 * asUResult * fyk * roofbeamResult.getBeamRightHeight();
                    mlby = 0.9 * asLResult * fyk * roofbeamResult.getBeamRightHeight();
                }
            }
            //如果是中柱
            else {
                CztCrsCalRoofbeamResult roofbeam1 = getRoofbeam(entity, roofbeamResults);
                CztCrsCalRoofbeamResult roofbeam2 = entity.getRoofBeam();
                Double tem1 = roofbeam1.getRigthAsPull() + roofbeam2.getLeftAsPull();
                Double tem2 = roofbeam1.getRigthAsPush() + roofbeam2.getLeftAsPush();
                fyk = Src4Enum.getBycode(entity.getRoofBeam().getBeamStirrupNum()) * 1000000;
                asUResult = tem1 > tem2 ? tem2 : tem1;
                List<CrsStoreyVo> storeyVos1 = storeyMap.get(entity.getFloorNum() - 1);
                List<CztCrsCalRoofbeamResult> roofbeamResults1 = storeyVos1.get(0).getRoofbeamResults();
                CztCrsCalRoofbeamResult roofbeam3 = getRoofbeam(lastEntity, roofbeamResults1);
                CztCrsCalRoofbeamResult roofbeam4 = lastEntity.getRoofBeam();
                Double tem3 = roofbeam3.getRigthAsPull() + roofbeam4.getLeftAsPull();
                Double tem4 = roofbeam3.getRigthAsPush() + roofbeam4.getLeftAsPush();
                asLResult = tem3 > tem4 ? tem4 : tem3;
                muby = 0.9 * asUResult * fyk * entity.getRoofBeam().getBeamLeftHeigth();
                mlby = 0.9 * asLResult * fyk * entity.getRoofBeam().getBeamLeftHeigth();
            }
        }
        //计算ki
        ki = calculateKi(entity, storeyMap);
        if (PlatformObjectUtils.isNotEmpty(nextEntity.getPillarCode())) {
            nextKi = calculateKi(nextEntity, storeyMap);
        }
        if (PlatformObjectUtils.isNotEmpty(lastEntity.getPillarCode())) {
            lastKi = calculateKi(lastEntity, storeyMap);
        }
        mucyb = muby * ki / (ki + nextKi);
        mlcyb = mlby * ki / (ki + lastKi);
        //与强梁弱柱比较，取小的值；
        //todo 这里先注释，改完增加判断，放开
//        mucy = mzu > mucyb ? mucyb : mzu;
//        mlcy = mzl > mlcyb ? mlcyb : mzl;
        HashMap<String, Double> resultMap = new HashMap<>();
        if ("1".equals(type)) {
            resultMap.put("mucy", mucy);
        } else if ("2".equals(type)) {
            resultMap.put("mlcy", mlcy);
        } else {
            resultMap.put("mucy", mucy);
            resultMap.put("mlcy", mlcy);
        }
        resultMap.put("muz", mzu);
        resultMap.put("mlz", mzl);
        resultMap.put("mucyb", mucyb);
        resultMap.put("mlcyb", mlcyb);
        return resultMap;
    }


    /**
     * @param crsStoreyVo
     * @return s
     */
    private CztCrsStoreyCalResult calculcateQw(CrsStoreyVo crsStoreyVo) {
        CztCrsStoreyCalResult storeyCalResult = new CztCrsStoreyCalResult();
        BeanUtil.copyPropertiesIgnoreEmpty(crsStoreyVo, storeyCalResult);


        return storeyCalResult;
    }

    //顶点附加地震作用系数取值σn 取值。
    private double calculateCoeff(double tg, double t1) {
        if (t1 > 1.4 * tg) {
            if (tg > 0.55)
                return 0.08 * t1 + 0.07;
            else if (tg > 0.35 && tg <= 0.55)
                return 0.08 * t1 + 0.01;
            else
                return 0.08 * t1 + 0.02;
        }
        return 0.0;
    }


    /**
     * 计算ki
     *
     * @param columnVO
     * @param crsStoreyVoMap
     * @return
     */
    private Double calculateKi(ColumnVO columnVO, Map<Integer, List<CrsStoreyVo>> crsStoreyVoMap) {
        Double ki = 0.00;
        Double i1 = 0.00;
        Double i2 = 0.00;
        Double i3 = 0.00;
        Double i4 = 0.00;
        if (PlatformObjectUtils.isNotEmpty(columnVO)) {
            Double ic = columnVO.getPillarSectionWidth() * Math.pow(columnVO.getPillarSectionHeight(), 3) / (12 * columnVO.getPillarHeight());
            Map<String, Double> iMap = calculateI(columnVO, crsStoreyVoMap);
            i2 = iMap.get("i1");
            i4 = iMap.get("i2");
            //计算I3 ;
            List<CrsStoreyVo> storeyVos = crsStoreyVoMap.get(columnVO.getFloorNum() - 1);
            if (PlatformObjectUtils.isNotEmpty(storeyVos)) {
                CrsStoreyVo crsStoreyVo1 = storeyVos.get(0);
                List<CztCrsCalRoofbeamResult> lastRoofBeams = crsStoreyVo1.getRoofbeamResults();
                List<ColumnVO> lastColumns = crsStoreyVo1.getColumnVOS();
                List<ColumnVO> collect = lastColumns.stream().filter(columnVO1 -> columnVO1.getPillarCode().equals(columnVO.getPillarCode())).collect(Collectors.toList());
                if (PlatformObjectUtils.isNotEmpty(collect)) {
                    Map<String, Double> i3Map = calculateI(collect.get(0), crsStoreyVoMap);
                    i1 = i3Map.get("i1");
                    i3 = i3Map.get("i2");
                }
            }
            Double iSum = i1 + i2 + i3 + i4;
            //如果是底层柱子
            if (columnVO.getFloorNum() == 1) {
                ki = iSum / (ic);
            } else {
                ki = iSum / (2 * ic);
            }
            return ki;
        } else {
            return ki;
        }
    }

    private Map<String, Double> calculateI(ColumnVO columnVO, Map<Integer, List<CrsStoreyVo>> crsStoreyVoMap) {
        double i1 = 0.00;
        double i2 = 0.00;
        Map<String, Double> resultMap = new HashMap<>();
        CrsStoreyVo crsStoreyVo = crsStoreyVoMap.get(columnVO.getFloorNum()).get(0);
        //先找梁
        List<CztCrsCalRoofbeamResult> roofbeamResults = crsStoreyVo.getRoofbeamResults();
        //去掉空值
        roofbeamResults = roofbeamResults.stream().filter(entity -> PlatformObjectUtils.isNotEmpty(entity)).collect(Collectors.toList());
        //计算i1 ;
        List<CztCrsCalRoofbeamResult> collect = roofbeamResults.stream().filter(roofbeamResult -> roofbeamResult.getBeamNum().contains("-" + columnVO.getPillarCode())).collect(Collectors.toList());
        if (PlatformObjectUtils.isNotEmpty(collect)) {
            CztCrsCalRoofbeamResult fromroofbeam = collect.get(0);
            List<ColumnVO> collect1 = crsStoreyVo.getColumnVOS().stream().filter(columnVO1 -> columnVO1.getPillarCode().equals(fromroofbeam.getBeamNum().split("-")[0])).collect(Collectors.toList());
            if (PlatformObjectUtils.isNotEmpty(collect1)) {
                ColumnVO columnVO1 = collect1.get(0);
                i1 = fromroofbeam.getBeamSectionWidth() * Math.pow(fromroofbeam.getBeamSectionHeight(), 3) / (12 * (fromroofbeam.getBeamSpan() - columnVO1.getPillarSectionHeight() / 2 - columnVO.getPillarSectionHeight() / 2));
            }
        }
        //计算i2 ;
        if (PlatformObjectUtils.isNotEmpty(columnVO.getRoofBeam())) {
            List<ColumnVO> toColumns = crsStoreyVo.getColumnVOS().stream().filter(columnVO1 -> columnVO1.getPillarCode().equals(columnVO.getRoofBeam().getBeamNum().split("-")[1])).collect(Collectors.toList());
            ColumnVO toColumn = toColumns.get(0);
            CztCrsCalRoofbeamResult roofBeam = columnVO.getRoofBeam();
            i2 = roofBeam.getBeamSectionWidth() * Math.pow(roofBeam.getBeamSectionHeight(), 3) / (12 * (roofBeam.getBeamSpan() - columnVO.getPillarSectionHeight() / 2 - toColumn.getPillarSectionHeight() / 2));
        }
        resultMap.put("i1", i1);
        resultMap.put("i2", i2);
        return resultMap;
    }

    /**
     * 获取前一根柱子
     *
     * @param columnVO
     * @param roofbeamResults
     * @return
     */
    private CztCrsCalRoofbeamResult getRoofbeam(ColumnVO columnVO, List<CztCrsCalRoofbeamResult> roofbeamResults) {
        roofbeamResults = roofbeamResults.stream().filter(entity -> PlatformObjectUtils.isNotEmpty(entity)).collect(Collectors.toList());
        List<CztCrsCalRoofbeamResult> collect = roofbeamResults.stream().filter(entity -> entity.getBeamNum().contains("-" + columnVO.getPillarCode())).collect(Collectors.toList());
        CztCrsCalRoofbeamResult roofbeamResult = collect.get(0);
        return roofbeamResult;
    }

    private String generateNum(Map<String, Object> paramMap) {
        List<CrsEntiretyParamVo> entiretys = new ArrayList();
        entiretys = (List<CrsEntiretyParamVo>) paramMap.get(FxfzConstants.entiretyPam);
        String jsonStr = JSON.toJSONString(entiretys.get(0));
        CrsEntiretyParamVo entiretyparam = JSON.parseObject(jsonStr, CrsEntiretyParamVo.class);
        //借用导入时候生成的number ;
        if (PlatformObjectUtils.isEmpty(entiretyparam.getNumber())) {
            String number =
                    GenerationNumberUtil.getCityInitials(entiretyparam.getProvince()) +
                            GenerationNumberUtil.type("钢筋混凝土结构", entiretyparam.getStructureType1()) +
                            GenerationNumberUtil.getFs(entiretyparam.getFortification()) +
                            generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_JZWYSX_KEY);
            entiretyparam.setNumber(number);
            List<CrsEntiretyParamVo> entireparams = new ArrayList();
            entireparams.add(entiretyparam);

            paramMap.put(FxfzConstants.entiretyPam, entireparams);
            return number;
        } else {
            return entiretyparam.getNumber();
        }

    }


    public RestResponse moveBasicLibraryById(String dataId, String operate) {
        try {
            rcpInformationRepository.moveBasicLibraryById(dataId, operate);
            return RestResponse.succeed("成功");
        } catch (Exception e) {
            String errorMessage = "失败!";
            return RestResponse.fail(errorMessage);
        }
    }
}
